﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using Microsoft.Web.Administration;

namespace ApplicationRefresher
{
    class Program
    {
        static void Main(string[] args)
        {
            //Diese DLL einbinden für den ServerManager:
            //c:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll 

            //Servermanager verwenden um auf den lokalen IIS zuzugreifen
            ServerManager manager = new ServerManager();
            List<string> pages = new List<string>();

            // Die Auflistung aller Seiten auf dem Server ermitteln
            string sitedisplay = string.Empty;
            foreach (Site site in manager.Sites)
            {
                sitedisplay = sitedisplay + site.Name + ": ID= " + site.Id + "\n";
                string bindingdisplay = string.Empty;
                string port = string.Empty;
                string protokoll = "http";
                string host = "localhost";
                string appPath = string.Empty;

                foreach (Microsoft.Web.Administration.Binding binding in site.Bindings)
                {
                    if (binding.EndPoint != null && (binding.Protocol == "http" || binding.Protocol == "https"))
                    {
                        bindingdisplay = "  Binding:";
                        bindingdisplay += "\n   Host: " + binding.Host;
                        bindingdisplay += "\n   Port: " + binding.EndPoint.Port;
                        bindingdisplay += "\n   Protocol: " + binding.Protocol + "\n\n";

                        port = binding.EndPoint.Port.ToString();
                        protokoll = binding.Protocol;
                        host = string.IsNullOrEmpty(binding.Host) ? "localhost" : binding.Host;
                    }
                }

                foreach (Application app in site.Applications)
                {
                    appPath = app.Path;
                    //Alle Seiten URLs ermitteln
                    var url = string.Format("{0}://{1}:{2}{3}", protokoll, host, port, appPath);
                    pages.Add(url);
                    Console.WriteLine(url);
                }

                sitedisplay = "\n" + sitedisplay + bindingdisplay;
            }

            Console.WriteLine(sitedisplay);
            
            //Callback Funktion für SSL-Zugriffe festlegen.
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);

            //Alle Seiten die wir ermittelt haben mit einem WebRequest starten.
            //dieser WebRequest verwendet die Anmeldeinformationen der Konsolenanwendung.
            foreach (string page in pages)
            {
                Stopwatch stopwatch = new Stopwatch();
                try
                {
                    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(page);
                    request.Method = "GET";
                    request.UseDefaultCredentials = false;
                    request.PreAuthenticate = true;
                    request.Credentials = CredentialCache.DefaultCredentials;
                    Console.WriteLine("Page: {0} | Starting...", page);
                    stopwatch.Start();
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Console.WriteLine("Page: {0} | Status: {1}", page, response.StatusCode);
                }
                catch (Exception exception)
                {
                    Console.WriteLine("Page: {0} | Status: {1} | Message: {2}", page, "Error", exception.Message);
                }
                finally
                {
                    stopwatch.Stop();
                    Console.WriteLine("Page: {0} | Startdauer: {1} ms \n\n", page, stopwatch.ElapsedMilliseconds);
                }
            }

            Console.WriteLine("DONE!");
            Console.ReadLine();
        }

        /// <summary>
        /// Callback Funktion für SSL Aufrufe immer mit True bestätigen auch wenn das Zertifikat evtl. nicht valide ist. Für z.B. selbstsignierte Zertifikate im IIS
        /// </summary>
        public static bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, 
                                                   System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}
